﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Web;
using System.Reflection;
using System.ComponentModel;

namespace KeanuMvc.Reference {

    public static class ToSomeThing {

        /// <summary>
        /// Change object entities to json string format
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJson(this object obj) {
            System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            return serializer.Serialize(obj);
        }

        /// <summary>
        /// Change object entities to json string format
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="depth"></param>
        /// <returns></returns>
        public static string ToJson(this object obj, int depth) {
            System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            serializer.RecursionLimit = depth;
            return serializer.Serialize(obj);
        }

        /// <summary>
        /// Replace Special Character
        /// </summary>
        /// <param name="StringText"></param>
        /// <param name="CharReplaced"></param>
        /// <returns></returns>
        public static string ReplaceSpecialChar(this string StringText, string CharReplaced) {
            string strCleanText = string.Empty;
            try {
                strCleanText = Regex.Replace(StringText, @"[,><?!@#$%^&*():';]", CharReplaced);
                strCleanText = Regex.Replace(strCleanText, @"\s+", CharReplaced).ToLower();
            } catch {
            }
            return strCleanText;

        }

        /// <summary>
        /// Round UP
        /// </summary>
        /// <param name="ValueToRound"></param>
        /// <returns></returns>
        public static double RoundUp(this double ValueToRound) {
            return Math.Round(ValueToRound + 0.5, MidpointRounding.ToEven);
        }

        /// <summary>
        /// Change to indonesian sample  Senin, 1 Januari 1980
        /// </summary>
        /// <param name="ObjectDateTime">Date Object</param>
        /// <param name="IncludeTime"></param>
        /// <returns></returns>
        public static string ToLongIndonesian(this DateTime ObjectDateTime, bool IncludeTime) {
            Dictionary<string, string> dayIndonesia = new Dictionary<string, string>();
            dayIndonesia.Add("monday", "Senin");
            dayIndonesia.Add("tuesday", "Selasa");
            dayIndonesia.Add("wednesday", "Rabu");
            dayIndonesia.Add("thursday", "Kamis");
            dayIndonesia.Add("friday", "Jumat");
            dayIndonesia.Add("saturday", "Sabtu");
            dayIndonesia.Add("sunday", "Minggu");

            Dictionary<string, string> monthIndonesia = new Dictionary<string, string>();
            monthIndonesia.Add("1", "Januari");
            monthIndonesia.Add("2", "February");
            monthIndonesia.Add("3", "Maret");
            monthIndonesia.Add("4", "April");
            monthIndonesia.Add("5", "Mei");
            monthIndonesia.Add("6", "Juni");
            monthIndonesia.Add("7", "Juli");
            monthIndonesia.Add("8", "Agustus");
            monthIndonesia.Add("9", "September");
            monthIndonesia.Add("10", "Oktober");
            monthIndonesia.Add("11", "Nopember");
            monthIndonesia.Add("12", "Desember");

            string strDateTime = string.Empty;
            try {
                strDateTime = dayIndonesia[ObjectDateTime.DayOfWeek.ToString().ToLower()] + ", " + ObjectDateTime.Day.ToString() + " " + monthIndonesia[ObjectDateTime.Month.ToString()] + " " + ObjectDateTime.Year.ToString();
            } catch {
            }
            if (IncludeTime) {
                strDateTime += " " + ObjectDateTime.Hour.ToString("00") + ":" + ObjectDateTime.Minute.ToString("00") + ":" + ObjectDateTime.Second.ToString("00");
            }
            return strDateTime;
        }

        /// <summary>
        /// Change to indonesian sample  01-01-1980
        /// </summary>
        /// <param name="ObjectDateTime">Object Date</param>
        /// <param name="IncludeTime"></param>
        /// <returns></returns>
        public static string ToShortIndonesian(this DateTime ObjectDateTime, bool IncludeTime) {
            string strDateTime = string.Empty;
            try {
                strDateTime = ObjectDateTime.Day.ToString("00") + "/" + ObjectDateTime.Month.ToString("00") + "/" + ObjectDateTime.Year.ToString("0000");
            } catch {
            }
            if (IncludeTime) {
                strDateTime += " " + ObjectDateTime.Hour.ToString("00") + ":" + ObjectDateTime.Minute.ToString("00") + ":" + ObjectDateTime.Second.ToString("00");
            }
            return strDateTime;
        }

        public static string AddDoubleQuote(this string StringText) {
            return "\"" + StringText + "\"";
        }

        public static bool IsAjaxRequest(this System.Web.HttpRequest request) {
            if (request == null) {
                throw new ArgumentNullException("request");
            }

            return (request["X-Requested-With"] == "XMLHttpRequest") || ((request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest"));
        }

        public static string NullSafeToString(this object obj) {
            return obj != null ? obj.ToString() : String.Empty;
        }

        public static T ToType<T>(this IConvertible obj) {
            Type t = typeof(T);
            Type u = Nullable.GetUnderlyingType(t);

            if (u != null) {
                if (obj == null)
                    return default(T);

                return (T)Convert.ChangeType(obj, u);
            } else {
                return (T)Convert.ChangeType(obj, t);
            }
        }

        public static T PostHandler<T>(this object obj) {
            PropertyInfo[] postProperties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo item in postProperties) {
                if (HttpContext.Current.Request[item.Name] != null) {
                    try {
                        if (item.PropertyType == typeof(DateTime?)) {
                            item.SetValue(obj, HttpContext.Current.Request[item.Name].ToType<DateTime?>(), null);
                        } else if (item.PropertyType == typeof(Int32?)) {
                            item.SetValue(obj, HttpContext.Current.Request[item.Name].ToType<Int32?>(), null);
                        } else if (item.PropertyType == typeof(Decimal?)) {
                            item.SetValue(obj, HttpContext.Current.Request[item.Name].ToType<Decimal?>(), null);
                        } else {
                            item.SetValue(obj, Convert.ChangeType(HttpContext.Current.Request[item.Name], item.PropertyType), null);
                        }
                    } catch { }
                }
            }
            return (T)obj;
        }

        public static T SetToHastable<T>(this object obj, IDictionary data) {
            PropertyInfo[] postProperties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo item in postProperties) {
                if (data.Contains(item.Name)) {
                    data[item.Name] = item.GetValue(obj, null).NullSafeToString();
                } else {
                    data.Add(item.Name, item.GetValue(obj, null).NullSafeToString());
                }
            }
            return (T)obj;
        }

        public static T ChangeObject<T>(this object obj, object ToObject) {
            PropertyInfo[] fromProperties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo[] toProperties = ToObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            for (int i = 0; i < fromProperties.Count(); i++) {
                try {
                    if (fromProperties[i].Name == toProperties[i].Name) {
                        object valueToSet = fromProperties[i].GetValue(obj, null);
                        toProperties[i].SetValue(ToObject, valueToSet, null);
                    }
                } catch { }
            }

            return (T)ToObject;
        }

    }

}
